﻿// DigitalDesign
// Project: InformationBoard
// Developer: Syzdykov Sergey
// Created: 09.11.2011
// Last change: 11.11.2011
// Description: implementation of AdminService

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Server
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "AdminService" in both code and config file together.
    public class AdminService : IAdminService
    {
        private DataModelContainer context;

        public AdminService()
        {
            context = Context.Instance;
        }

        #region clients

        public List<ClientNotEF> GetListOfClients()
        {
            List<ClientNotEF> listOfClientsNotEF = new List<ClientNotEF>();

            foreach (var client in context.ClientDevices)
            {
                ClientNotEF clientNotEF = new ClientNotEF(client);
                listOfClientsNotEF.Add(clientNotEF);
            }
            return listOfClientsNotEF;
        }

        public List<ClientNotEF> GetListOfStationClients(int id)
        {
            List<ClientNotEF> listOfclientsNotEF = new List<ClientNotEF>();

            foreach (var client in context.ClientDevices)
            {
                if (client.Location.StationId == id)
                {
                    ClientNotEF clientNotEF = new ClientNotEF(client);
                    listOfclientsNotEF.Add(clientNotEF);
                }
            }
            return listOfclientsNotEF;
        }

        public bool AddClient(ClientNotEF clientNotEF)
        {
            try
            {
                ClientDevice client = new ClientDevice();
                client.ClientUpdate(clientNotEF);
                context.AddToClientDevices(client);
                context.SaveChanges();

                //добавим запись в таблицу версий
                ClientChanx changes = new ClientChanx();
                changes.ClientDevice_Id = (from c in context.ClientDevices select c.Id).Max();

                // здесь был некто
                // некто удалил строчку кода
                // cc.DataVersion = 0;

                context.AddToClientChanges(changes);
                context.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool DeleteClient(int id)
        {
            try
            {
                var toDelete =
                    (from c in context.ClientDevices where c.Id == id select c).First();
                                              
                context.DeleteObject(toDelete);
                context.SaveChanges();
                
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }


        public bool UpdateClient(ClientNotEF clientNotEF)
        {
            try
            {
                var toUpdate =
                    (from c in context.ClientDevices where c.Id == clientNotEF.Id select c).First();

                toUpdate.ClientUpdate(clientNotEF);
                context.SaveChanges();
                DataVersionManager.Instance.IncSettingsVersion(toUpdate.Id);
                //Helper.IncDataVersion(toUpdate.Id);
                return true;
            }
            catch (Exception)
            {
                return false;
            }

        }

        #endregion

        #region stations

        //методы работы с вокзалами
        public List<StationNotEF> GetListOfStations()
        {
            List<StationNotEF> listOfStationsNotEF = new List<StationNotEF>();

            foreach (var station in context.Stations)
            {
                StationNotEF stationNotEF = new StationNotEF(station);
                listOfStationsNotEF.Add(stationNotEF);
            }

            return listOfStationsNotEF;

        }

        public bool AddStation(StationNotEF stationNotEF)
        {
            try
            {
                Station station = new Station();
                station.StationUpdate(stationNotEF);
                context.AddToStations(station);
                context.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool DeleteStation(int id)
        {
            try
            {
                var toDelete =
                    (from c in context.Stations where c.Id == id select c).First();

                while (toDelete.Locations.Count > 0)
                {
                    DeleteLocation(toDelete.Locations.First().Id);
                }
                
                context.DeleteObject(toDelete);
                context.SaveChanges();                
                return true;
            }
            catch (Exception )
            {
                return false;
            }
        }

        public bool UpdateStation(StationNotEF stationNotEF)
        {
            try
            {
                var toUpdate =
                    (from c in context.Stations where c.Id == stationNotEF.Id select c).First();

                toUpdate.StationUpdate(stationNotEF);
                context.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        #endregion

        #region locations

        //методы работы с локациями

        public List<LocationNotEF> GetListOfStationLocations(int id)
        {
            List<LocationNotEF> listOfLocationsNotEF = new List<LocationNotEF>();

            foreach (var location in context.Locations)
            {
                if (location.StationId == id)
                {
                    LocationNotEF locationNotEF = new LocationNotEF(location);
                    listOfLocationsNotEF.Add(locationNotEF);
                }
            }
            return listOfLocationsNotEF;
        }

        public bool AddLocation(LocationNotEF locationNotEF)
        {
            try
            {
                Location location = new Location();
                location.LocationUpdate(locationNotEF);
                context.AddToLocations(location);
                context.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool DeleteLocation(int id)
        {
            try
            {
                var toDelete =
                    (from c in context.Locations where c.Id == id select c).First();

                //каскадное удаление средствами Entity Framework породило некоторые проблемы
                //так что частично это реализовано руками в ниже идущем коде
                
                var scheduleService = new ScheduleService();                

                while (toDelete.Schedules.Count > 0)
                {
                    scheduleService.DeleteSchedule(toDelete.Schedules.First().Id);
                }

                while (toDelete.ScheduleChanges.Count > 0)
                {
                    scheduleService.DeleteScheduleChanges(toDelete.ScheduleChanges.First().Id);
                }

                while(toDelete.ClientDevices.Count > 0)
                {
                    DeleteClient(toDelete.ClientDevices.First().Id);
                }
                
                context.DeleteObject(toDelete);
                context.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool UpdateLocation(LocationNotEF locationNotEF)
        {

            try
            {
                var toUpdate =
                    (from c in context.Locations where c.Id == locationNotEF.Id select c).First();

                toUpdate.LocationUpdate(locationNotEF);
                context.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        #endregion

        #region passengers

        public List<ClassesOfPassengerNotEF> GetListOfPassengers()
        {
            List<ClassesOfPassengerNotEF> listOfPassengersNotEF = new List<ClassesOfPassengerNotEF>();

            foreach (var classOfPassengers in context.ClassesOfPassengers)
            {
                ClassesOfPassengerNotEF classNotEF = new ClassesOfPassengerNotEF(classOfPassengers);
                listOfPassengersNotEF.Add(classNotEF);
            }
            return listOfPassengersNotEF;
        }

        #endregion

    }
}

